package com.mp3.player.views
{
	import com.mp3.player.events.TrackEvent;
	import com.mp3.player.events.TrackListEvent;
	import com.mp3.player.skins.defaultSkin.DefaultPlaylistSkin;
	import com.mp3.player.vos.Track;
	import com.mp3.player.vos.TrackList;
	
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;
	
	import mx.core.UIComponent;
	import mx.styles.CSSStyleDeclaration;
	import mx.styles.StyleManager;
	
	import spark.components.Button;
	import spark.components.List;
	import spark.components.TitleWindow;
	import spark.components.supportClasses.SkinnableComponent;
	import spark.events.TrackBaseEvent;
	
	[Event(name="play", type="com.mp3.player.events.TrackEvent")]
	
	/**
	 *  Dispatched when the user presses the add button control.
	 *
	 *  @eventType com.mp3.player.events.TrackListEvent.ADD
	 */
	[Event(name="add", type="com.mp3.player.events.TrackListEvent")]

	/**
	 *  Dispatched when the user presses the save button control.
	 *
	 *  @eventType com.mp3.player.events.TrackListEvent.SAVE
	 */
	[Event(name="save", type="com.mp3.player.events.TrackListEvent")]
	
	/**
	 *  Dispatched when the user presses the load button control.
	 *
	 *  @eventType com.mp3.player.events.TrackListEvent.LOAD_TRACK_LIST
	 */
	[Event(name="loadTrackList", type="com.mp3.player.events.TrackListEvent")]
	
	public class Playlist extends SkinnableComponent
	{
		/**
		 * @private
		 * This static function needs to set default styles to the component 
		 * without creating separate css file.
		 */
		private static function initializeStyles():void
		{
			var styles:CSSStyleDeclaration = StyleManager.getStyleManager(null).getStyleDeclaration("com.mp3.player.views.Playlist");
			if(!styles)
				styles = new CSSStyleDeclaration();
			
			styles.defaultFactory = function():void
			{	
				// default styles for the component
				this.skinClass = DefaultPlaylistSkin;
			}
			StyleManager.getStyleManager(null).setStyleDeclaration("com.mp3.player.views.Playlist", styles, false);
		}
		initializeStyles();
		
		[SkinPart(required="true")]
		/**
		 *  A skin part that defines the list of tracks. 
		 */
		public var list:List;
		
		[SkinPart(required="false")]
		/**
		 *  A skin part that defines the add button. 
		 */
		public var addButton:Button;
		
		[SkinPart(required="false")]
		/**
		 *  A skin part that defines the save button. 
		 */
		public var saveButton:Button;
		
		[SkinPart(required="false")]
		/**
		 *  A skin part that defines the remove button. 
		 */
		public var removeButton:Button;
		
		[SkinPart(required="false")]
		/**
		 *  A skin part that defines the load track list button. 
		 */
		public var loadButton: Button;
		
		private var _trackList: TrackList;
		
		private var _currentTrack: Track;
		private var _currentTrackChanged: Boolean;
		
		private var _listChanged: Boolean = false;
		
		/**
		 * Constructor
		*/
		public function Playlist()
		{
			super();
		}
		
		//--------------------------------------------------------------------------
		//
		//  Properties
		//
		//--------------------------------------------------------------------------
		[Bindable]
		public function get trackList():TrackList
		{
			return _trackList;
		}
		public function set trackList(value: TrackList): void
		{
			_trackList = value;
			if (list)
			{
				list.dataProvider = _trackList.tracks;
			}
		}
		
		[Bindable]
		public function get currentTrack(): Track
		{
			return _currentTrack;
		}
		public function set currentTrack(value: Track): void
		{
			_currentTrack = value;
			_currentTrackChanged = true;
			invalidateProperties();
		}
		
		//--------------------------------------------------------------------------
		//
		//  Lyfe Cycle
		//
		//--------------------------------------------------------------------------
		override protected function commitProperties(): void
		{
			super.commitProperties();
			
			if (_listChanged)
			{
				list.doubleClickEnabled = true;
				list.allowMultipleSelection = false;
				
				if (trackList != null)
				{
					list.dataProvider = trackList.tracks;
					_currentTrackChanged = true;
				}
				list.addEventListener(MouseEvent.DOUBLE_CLICK, onListDoubleClick);
				_listChanged = false;
			}
			
			if (_currentTrackChanged)
			{
				if (list != null)
				{
					var currentIndex: int = list.selectedIndex;
					
					list.selectedItem = currentTrack;
					var index: int = trackList.getTrackIndex(currentTrack);
					list.ensureIndexIsVisible(index);
				}
				_currentTrackChanged = false;
			}
		}
		
		override protected function partAdded(partName:String, instance:Object):void
		{
			super.partAdded(partName, instance);
			
			switch(instance)
			{
				case list:
					_listChanged = true;
					invalidateProperties();
					break;
				
				case addButton:
					addButton.addEventListener(MouseEvent.CLICK, addTrackHandler);
					break;
				
				case removeButton:
					removeButton.addEventListener(MouseEvent.CLICK, removeTrackHandler);
					break;
				
				case saveButton:
					saveButton.addEventListener(MouseEvent.CLICK, saveTrackHandler);
					break;
				
				case loadButton:
					loadButton.addEventListener(MouseEvent.CLICK, onLoadTrackList);
					break;
			}
		}
		
		
		override protected function partRemoved(partName:String, instance:Object):void
		{
			super.partRemoved(partName, instance);
			
			switch(instance)
			{
				case list:
					list.removeEventListener(MouseEvent.DOUBLE_CLICK, onListDoubleClick);
					break;
				
				case addButton:
					addButton.removeEventListener(MouseEvent.CLICK, addTrackHandler);
					break;
				
				case removeButton:
					removeButton.removeEventListener(MouseEvent.CLICK, removeTrackHandler);
					break;
				
				case saveButton:
					saveButton.removeEventListener(MouseEvent.CLICK, saveTrackHandler);
					break;
				
				case loadButton:
					loadButton.removeEventListener(MouseEvent.CLICK, onLoadTrackList);
					break;
			}
		}
		
		//--------------------------------------------------------------------------
		//
		//  Event handlers
		//
		//--------------------------------------------------------------------------
		private function onListDoubleClick(event: MouseEvent = null): void
		{
			var track: Track = list.selectedItem as Track;
			
			var trackEvent: TrackEvent = new TrackEvent(TrackEvent.PLAY);
			trackEvent.track = track;
			dispatchEvent(trackEvent);
		}
	
		/**
		 * Handler for add button click event.
		 *  
		 * @param event MouseEvent
		 */		
		private function addTrackHandler(event: MouseEvent = null): void
		{
			dispatchEvent(new TrackListEvent(TrackListEvent.ADD));
		}
		
		/**
		 * Handler for remove button click event.
		 *  
		 * @param event MouseEvent
		 */	
		private function removeTrackHandler(event: MouseEvent = null): void
		{
			trackList.removeTrack(list.selectedItem);
		}
		
		/**
		 * Handler for save button click event.
		 *  
		 * @param event MouseEvent
		 */	
		private function saveTrackHandler(event: MouseEvent = null): void
		{
			dispatchEvent(new TrackListEvent(TrackListEvent.SAVE, trackList));
		}
		
		/**
		 * Handler for load track button click handler 
		 * @param event
		 */		
		private function onLoadTrackList(event: MouseEvent = null): void
		{
			dispatchEvent(new TrackListEvent(TrackListEvent.LOAD_TRACK_LIST));
		}
	}
}